package com.hotelvip.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hotelvip.common.exception.ServiceException;
import com.hotelvip.common.pojo.PageObject;
import com.hotelvip.common.utils.IdcardUtils;
import com.hotelvip.common.utils.NumberUtil;
import com.hotelvip.common.utils.ShiroUtils;
import com.hotelvip.dao.UserLabelMapper;
import com.hotelvip.dao.UserMapper;
import com.hotelvip.dao.VipUserMapper;
import com.hotelvip.entity.Label;
import com.hotelvip.entity.User;
import com.hotelvip.entity.UserLabel;
import com.hotelvip.service.LabelService;
import com.hotelvip.service.UserService;
import com.hotelvip.service.batch.UserLabelService;
import com.hotelvip.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 客户用户实现类
 *
 * @author Lzh
 * @date 2020/12/14 14:42
 */
@Service
@Slf4j
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LabelService labelService;

    @Autowired
    private UserLabelService userLabelService;

    @Autowired
    private UserLabelMapper userLabelMapper;

    @Autowired
    private VipUserMapper vipUserMapper;

    /**
     * 保存客户用户信息
     *
     * @param userVo
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void saveUser(UserVo userVo) {
        //校验
        //证件号码
        List<User> users = userMapper.selectList(new QueryWrapper<User>().lambda().in(User::getVStatus, 0, 1));
        User user = userVo.getUser();
        String cid = user.getCid();
        log.info("" + user.getIdType());
        log.info("" + !IdcardUtils.validateCard(cid));
        if (user.getIdType() == 1) {
            if (cid == null || cid.isEmpty() || !IdcardUtils.validateCard(cid)) {
                throw new ServiceException("(陆)证件号码不合法");
            }
        }
        if (user.getIdType() == 2) {
            if (cid == null || cid.isEmpty() || !IdcardUtils.validateHKCard(cid)) {
                throw new ServiceException("(港)证件号码不合法");
            }
        }
        if (userVo.getUser().getId() == null) {
            users.forEach(userdb -> {
                if (userdb.getCid().equals(cid)) {
                    throw new ServiceException("身份证号码重复");
                }
            });

        }
        log.info("证件号码验证通过");
        //手机号码
        String phone = user.getPhone();
        if (phone == null || phone.isEmpty() || !NumberUtil.isPhone(phone)) {
            throw new ServiceException("手机号码验证错误");
        }
        if (userVo.getUser().getId() == null) {
            users.forEach(userdb -> {
                if (userdb.getPhone().equals(phone)) {
                    throw new ServiceException("电话号码已被注册");
                }
            });
        }
        log.info("电话号码验证通过");

        //姓名
        if (user.getName() == null || user.getName() == "") {
            throw new ServiceException("客户用户名称不能为空");
        }
        //用户默认状态改为0，操作用户
        user.setVStatus(0)
                .setCreatedUser(ShiroUtils.getUsername())
                .setUpdatedUser(ShiroUtils.getUsername())
                .setDeleted(0);
        //添加
        try {
            this.saveOrUpdate(user);
            if (CollectionUtils.isNotEmpty(userVo.getLabels())) {
                //获取labelsIds
                List<Integer> labelIds = userVo.getLabels().stream().map(Label::getId).collect(Collectors.toList());
                //生成中间表对象
                List<UserLabel> userLabels = labelIds.stream().map(labelId ->
                        new UserLabel().setUserId(user.getId()).setLabelId(labelId)).collect(Collectors.toList());
                //保存添加到中间表
                userLabelService.saveBatch(userLabels);
            }
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    /**
     * 按照id查找用户
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public UserVo findUserById(Long id) {
        //校验
        if (id == null || id == 0) {
            throw new ServiceException("ID不能为空");
        }
        UserVo userVo = new UserVo().setUser(userMapper.selectById(id)).setLabels(labelService.selectLabelById(id));
        return userVo;
    }

    /**
     * 查找所有用户信息
     *
     * @param current 当前页面
     * @param size    页面大小
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public PageObject<UserVo> findUsers(Long current, Long size) {

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //按照更新时间进行排序排序
        wrapper.lambda().orderByDesc(User::getUpdatedTime).in(User::getVStatus, 0, 1);
        // 2. 分页对象
        IPage<User> iPage = new Page<>(current, size);
        //查询数据库获取数据
        iPage = super.page(iPage, wrapper);

        List<User> userList = iPage.getRecords();
        if (CollectionUtils.isEmpty(userList)) {
            throw new ServiceException("查询失败或没有用户");
        }

        List<UserVo> userVos = new ArrayList<>();
        for (User user : userList) {
            //通过用户的id获取Label set到UserVo
            List<Label> labels = labelService.selectLabelById(user.getId());
            UserVo userVo = new UserVo();
            if (CollectionUtils.isNotEmpty(labels)) {
                userVos.add(userVo.setUser(user).setLabels(labels));
            } else {
                userVos.add(userVo.setUser(user));
            }
        }
        //总条数
        long total = iPage.getTotal();
        //总页数
        long pages = iPage.getPages();
        return PageObject.setPageObject(total, userVos, size, current);
    }

    /**
     * 按照id修改该用户信息
     *
     * @param userVo
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateUserInfo(UserVo userVo) {
        if (userVo.getUser() == null) {
            throw new ServiceException("参数有误");
        }
        User user = userVo.getUser();
        //验证
        if (user.getId() == null || userMapper.selectById(user.getId()) == null) {
            throw new ServiceException("用户不存在！");
        }
        if (user.getPhone() != null && !NumberUtil.isPhone(user.getPhone())) {
            throw new ServiceException("手机号码不合法！");
        }
        if (user.getCid() != null && !IdcardUtils.validateCard(user.getCid())) {
            throw new ServiceException("证件信息不合法！");
        }
        //修改用户
        user.setUpdatedUser(ShiroUtils.getUsername());
        //执行
        userMapper.updateById(user);
        //删除就的label 添加新的label
        if (userVo.getLabels() != null && userVo.getLabels().size() != 0) {
            userLabelMapper.delete(new UpdateWrapper<UserLabel>().lambda().eq(UserLabel::getUserId, user.getId()));
            //获取labelsIds
            List<Integer> labelIds = userVo.getLabels().stream().map(Label::getId).collect(Collectors.toList());
            //生成中间表对象
            List<UserLabel> userLabels = labelIds.stream().map(labelId ->
                    new UserLabel().setUserId(user.getId()).setLabelId(labelId)).collect(Collectors.toList());
            //保存添加到中间表
            userLabelService.saveBatch(userLabels);
        }
    }

    /**
     * 根据id集合删除客户用户信息
     *
     * @param ids
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void deleteUserByIds(List<Long> ids) {

        //删除前先判断用户中是否存在会员
        //如果用户为会员则给与警告 在会员模块进行删除用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(User::getId, ids);
        List<User> list = this.list(wrapper);

        if (list.isEmpty()) {
            throw new ServiceException("会员不存在");
        }
        //判断是否是删除状态
        List<Integer> delete = list.stream().map(User::getDeleted).collect(Collectors.toList());
        for (Integer deleted : delete) {
            if (deleted == 1) {
                throw new ServiceException("存在已删除的用户");
            }
        }
        //判断删除的是否为非会员
        List<Integer> stasus = list.stream().map(User::getVStatus).collect(Collectors.toList());
        for (Integer stasu : stasus) {
            if (stasu != 0) {
                throw new ServiceException("无权限删除会员用户");
            }
        }
        //将删除状态更改为1 表示已删除
        //list.stream().forEach(user -> user.setDeleted(1));
        //此处使用了逻辑删除注解
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().in(User::getId, ids);
        boolean b = this.remove(updateWrapper);
        if (!b) {
            throw new ServiceException("删除失败");
        }
    }

    @Override
    public List<User> selectName(String key, Integer userType) {

        //TODO 目前先使用系统用户代替员工推荐人
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (key != null && key != "") {
            //查询关键字除去前后空格
            String trim = key.trim();
            wrapper.lambda().like(User::getName, trim).or().like(User::getPhone, trim);
        }
        wrapper.lambda().select(User::getName, User::getPhone, User::getId).eq(User::getVStatus, userType);
        //通过分页对象,默认给出查询结果前50条,加入关键字越准确得出的结果条数越少
        int page = 1, rows = 50;
        IPage<User> iPage = new Page<>(page, rows);
        iPage = page(iPage, wrapper);
        List<User> userList = iPage.getRecords();
        //判断获取的集合是否为空
        if (CollectionUtils.isEmpty(userList)) {
            return null;
        }
        return userList;
    }

    @Override
    public List<User> getDeleteUsers() {
        List<User> userList = userMapper.getDeleteUsers();
        return userList;
    }

}
